package com.macro.cloud.hystrixservice.controller;

import cn.hutool.core.thread.ThreadUtil;
import com.macro.cloud.hystrixservice.domain.CommonResult;
import com.macro.cloud.hystrixservice.domain.User;
import com.macro.cloud.hystrixservice.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

@RestController
@RequestMapping("/user")
public class UserHystrixController {
    @Autowired
    private UserService userService;

    @GetMapping("/testFallback/{id}")
    public CommonResult testFallback(@PathVariable Long id) {
        return userService.getUser(id);
    }

    @GetMapping("/testCommand/{id}")
    public CommonResult testCommand(@PathVariable Long id) {
        return userService.getUserCommand(id);
    }

    @GetMapping("/testException/{id}")
    public CommonResult testException(@PathVariable Long id) {
        return userService.getUserException(id);
    }

    @GetMapping("/testCache/{id}")
    public CommonResult testCache(@PathVariable Long id) {
        userService.getUserCache(id);
        userService.getUserCache(id);
        userService.getUserCache(id);
        return new CommonResult("操作成功",200);
    }

    /**
     * 先调用getUserFuture两次服务，在200毫秒之后进行第三次服务的调用
     * 我们使用@HystrixCollapser实现请求的合并。所有对getUserFuture方法进行多次调用都会转化为
     * 对getUserByIds的单次调用
     * 最终的结果：
     * : getUserByIds:[2, 1]
     *   getUserByIds:[3]
     * 说明：由于我们在Service中设置了 @HystrixProperty(name = "timerDelayInMilliseconds",value = "100")100毫秒进行一次
     *      请求合并，所以前两次请求被合并到一起了getUserByIds:[2, 1]
     *      最后一次请求自己单独合并了 getUserByIds:[3]
     * @return
     * @throws ExecutionException
     * @throws InterruptedException
     */
    @GetMapping("/testCollapser")
    public CommonResult testCollapser() throws ExecutionException, InterruptedException {
        Future<User> future1 = userService.getUserFuture(1L);
        Future<User> future2 = userService.getUserFuture(2L);
        future1.get(); //获取结果
        future2.get(); //获取结果
        //ThreadUtil.safeSleep(200)的作用是让当前线程暂停执行，即休眠200毫秒。
        // 这个方法是在ThreadUtil类中定义的，它提供了一种安全的方式来控制线程的休眠时间。
        // 使用safeSleep方法可以确保线程在休眠期间不会被意外中断或异常中断，
        // 从而增加了线程的稳定性和可靠性。通常情况下，线程休眠用于实现一些需要间隔一定时间执行的任务，
        // 或者用于控制线程的执行速度。
        ThreadUtil.safeSleep(200);
        Future<User> future3 = userService.getUserFuture(3L);
        future3.get();
        return new CommonResult("操作成功",200);
    }



}
